/**
 * NameHelper.java		26/06/2009
 */
package org.jopris.util;

/**
 * This class provide various utilities for converting from standard VM
 * descriptions (fields, methods, classes, types, etc....) into qualified names
 * (and vice versa).
 * 
 * @author Guy Nir
 * @version 1.00
 */
public class NameHelper {

	/**
	 * Convert an internal field name into a qualified class name. For example,
	 * the internal description <i>Ljava/lang/Object;</i> is converted to
	 * <code>java.lang.Object</code>. A description of 'Z' is converted to
	 * primitive type <code>boolean</code>.
	 * 
	 * @param desc
	 *            Internal class name description. Must conform to
	 *            <code>classname</code> internal description, as described in
	 *            <a href="http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#14152"
	 *            >JLS#4.3.2</a>
	 * 
	 * @return Fully qualified name of class.
	 * 
	 * @throws IllegalArgumentException
	 *             If either <i>desc</i> is <code>null</code> or takes an
	 *             invalid format.
	 */
	public static String internalFieldToQualifiedClassName(String desc) throws IllegalArgumentException {
		Assert.assertNotNull(desc, "Internal error: classNameDescriptor cannot be null.");
		String classname;

		int len = desc.length();
		if (len == 0) {
			throw new IllegalArgumentException("Internal error: Invalid description format (empty!).");
		}

		switch (desc.charAt(0)) {
		case 'B':
			classname = "boolean";
			break;
		case 'C':
			classname = "char";
			break;
		case 'D':
			classname = "double";
			break;
		case 'F':
			classname = "float";
			break;
		case 'I':
			classname = "int";
			break;
		case 'J':
			classname = "long";
			break;
		case 'L':
			if (len < 3 || desc.charAt(len - 1) != ';') {
				StringBuilder buf = new StringBuilder();
				buf
						.append("Internal error: classNameDescriptor does not conform with VM description format (");
				buf.append(desc);
				buf.append(").");
				throw new IllegalArgumentException(buf.toString());
			}
			classname = toQualifiedClassName(desc.substring(1, len - 1));
			break;
		case 'S':
			classname = "short";
			break;
		case 'Z':
			classname = "boolean";
			break;
		case '[':
			classname = "array";
			break;
		default:
			throw new IllegalArgumentException(
					"Internal error: Unknown field description type/format: " + desc);
		}

		return classname;
	}

	public static String toInternalClassName(Class<?> cls) throws IllegalArgumentException {
		Assert.assertNotNull(cls, "Class cannot be null.");
		return "L" + cls.getName().replace('.', '/') + ";";
	}

	private static String toQualifiedClassName(String desc) {
		return desc.replace('/', '.');
	}
}
